#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#       GUI.py
#       
#       Copyright 2011 Guglielmo Saggiorato <astyonax@astyonax-laptop>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

#       Original GUI from unknown author - I'm unable to find the web page again

import gtk
import pygtk
import os
import warnings

class App (object):

    ui_defs = """<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<property name="window_position">center</property>
<property name="icon_name">modem</property>
<signal name="destroy" handler="on_window_destroy"/>
<child>
  <object class="GtkTable" id="table1">
    <property name="visible">True</property>
    <property name="border_width">16</property>
    <property name="n_rows">6</property>
    <property name="n_columns">2</property>
    <child>
      <object class="GtkLabel" id="label1">
        <property name="visible">True</property>
        <property name="xalign">1</property>
        <property name="xpad">12</property>
        <property name="label" translatable="yes">Username:</property>
      </object>
    </child>
    <child>
      <object class="GtkLabel" id="label2">
        <property name="visible">True</property>
        <property name="xalign">1</property>
        <property name="xpad">12</property>
        <property name="label" translatable="yes">Password:</property>
      </object>
      <packing>
        <property name="top_attach">1</property>
        <property name="bottom_attach">2</property>
      </packing>
    </child>
    <child>
      <object class="GtkLabel" id="label3">
        <property name="visible">True</property>
        <property name="label" translatable="yes">Directory:</property>
      </object>
      <packing>
        <property name="top_attach">4</property>
        <property name="bottom_attach">5</property>
      </packing>
    </child>
    <child>
      <object class="GtkEntry" id="entry1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="invisible_char">•</property>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
      </packing>
    </child>
    <child>
      <object class="GtkHBox" id="hbox1">
        <property name="visible">True</property>
        <child>
          <object class="GtkEntry" id="entry2">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="visibility">False</property>
            <property name="invisible_char">•</property>
            <property name="activates_default">True</property>
            <property name="invisible_char_set">True</property>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="checkbutton1">
            <property name="label" translatable="yes">Show Password</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="draw_indicator">True</property>
            <signal name="toggled" handler="on_checkbutton1_toggled"/>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
        <property name="top_attach">1</property>
        <property name="bottom_attach">2</property>
      </packing>
    </child>
    <child>
      <object class="GtkFileChooserButton" id="filechooserbutton1">
        <property name="visible">True</property>
        <property name="border_width">12</property>
        <property name="action">select-folder</property>
        <property name="title" translatable="yes">Select A Direcoty</property>
        <signal name="selection_changed" handler="on_filechooserbutton1_selection_changed"/>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
        <property name="top_attach">4</property>
        <property name="bottom_attach">5</property>
      </packing>
    </child>
    <child>
      <object class="GtkHBox" id="hbox2">
        <property name="visible">True</property>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">Quit</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="border_width">13</property>
            <signal name="clicked" handler="on_button1_clicked"/>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button2">
            <property name="label" translatable="yes">Start Serving</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="border_width">12</property>
            <signal name="clicked" handler="on_button2_clicked"/>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
        <property name="top_attach">5</property>
        <property name="bottom_attach">6</property>
      </packing>
    </child>
    <child>
      <object class="GtkLabel" id="label4">
        <property name="visible">True</property>
        <property name="xalign">1</property>
        <property name="xpad">12</property>
        <property name="label" translatable="yes">Port:</property>
      </object>
      <packing>
        <property name="top_attach">2</property>
        <property name="bottom_attach">3</property>
      </packing>
    </child>
    <child>
      <object class="GtkHBox" id="hbox3">
        <property name="visible">True</property>
        <child>
          <object class="GtkSpinButton" id="spinbutton1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="invisible_char">•</property>
            <property name="adjustment">adjustment1</property>
            <signal name="value_changed" handler="on_spinbutton1_value_changed"/>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkAlignment" id="alignment1">
            <property name="visible">True</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
        <property name="top_attach">2</property>
        <property name="bottom_attach">3</property>
      </packing>
    </child>
    <child>
      <object class="GtkHBox" id="hbox4">
        <property name="visible">True</property>
        <child>
          <object class="GtkCheckButton" id="checkbutton2">
            <property name="label" translatable="yes">Anonymous</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="active">True</property>
            <property name="draw_indicator">True</property>
            <signal name="toggled" handler="on_checkbutton2_toggled"/>
          </object>
          <packing>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="checkbutton3">
            <property name="label" translatable="yes">Allow write access</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="draw_indicator">True</property>
            <signal name="toggled" handler="on_checkbutton3_toggled"/>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="right_attach">2</property>
        <property name="top_attach">3</property>
        <property name="bottom_attach">4</property>
      </packing>
    </child>
    <child>
      <placeholder/>
    </child>
    <child>
      <placeholder/>
    </child>
  </object>
</child>
</object>
<object class="GtkAdjustment" id="adjustment1">
<property name="value">2121</property>
<property name="upper">65535</property>
<property name="step_increment">1</property>
</object>
</interface>"""

    def __init__(self):
        if hasattr(self, 'name'):
            app_name = self.name
        else:
            print "warning: missing property 'name'"
            app_name = "ShareMe"
            
        self.builder = gtk.Builder()
        path = os.path.dirname('/'.join(__file__.split("/")[:-1]))
        self.builder.add_from_string(self.ui_defs)
        
        try:
            with warnings.catch_warnings() as w:
                warnings.simplefilter("error")
                self.builder.connect_signals(self)
        except RuntimeWarning as e:
            print "warning: " + str(e)
        
        for i in self.builder.get_objects():
            try:
                name = gtk.Buildable.get_name(i)
                if name in self.__dict__:
                    raise NameError, \
                        "Name '%s' collides with a member of %s" % \
                            (name, self.__class__.__name__)
                self.__dict__[name] = self.builder.get_object(name)
            except TypeError:
                pass
            if isinstance(i, gtk.Window):
                i.set_title(app_name)
        #~ if hasattr(self, 'finish_initializing'):
            #~ self.finish_initializing()
        #~ else:
            #~ print "warning: missing handler 'finish_initializing'"
        #gtk.main()
        
    #~ def serve(port, directory, anonymous=False, write=False,
        #~ username=None, password=None):
        #~ #""" change THIS """
        #~ if hasattr(self,'parent'):
            #~ print "start/stop server"
        #~ else:
            #~ pass
        #~ 
        #~ authorizer = DummyAuthorizer()
        #~ print write
        #~ perm = "elradfmw" if write else "elr"
        #~ if not anonymous:
            #~ authorizer.add_user(username, password, directory, perm=perm)
        #~ else:
            #~ authorizer.add_anonymous(directory, perm=perm)
        #~ handler = FTPHandler
        #~ handler.authorizer = authorizer
        #~ address = ("0.0.0.0", port)
        #~ ftpd = FTPServer(address, handler)
        #~ ftpd.serve_forever() # this isn't cancled propery :-(

class FtpGui (App):
    
    def __init__(self, parent):
       
        App.__init__(self)
        #calling gtk.statusicon with data members and methods
        #print dir(parent)
        
        self.parent=parent
        self.update()
        
    def update(self):
        self.port=self.parent.bind_port
        self.shares=self.parent.shares
        
        #take first user
        # and unpack infos to initialize the gui
        self.def_user=[x[1] for x in filter(lambda x:x[0],self.shares)][0]
        
        self.anonymous= True if self.def_user[0]==self.parent.anon_kw else False
        
        self.uname=''
        if not self.anonymous:
            self.uname=self.def_user[0]

        self._pw=self.def_user[1]
        self._dir=self.def_user[2]
        
        self.write = True if 'w' in self.def_user[3]  else False
       
        self.window1.connect("delete_event",self.on_window_destroy)
        
        self.spinbutton1.set_value(self.port)
        #self.spinbutton1.set_sensitive(False) 
        

        self.checkbutton2.set_active(self.anonymous)
        self.__anon_sensitivity()
        self.checkbutton3.set_active(self.write)
        #~ else:
            #~ self.entry1.set_text(self.uname)
            #~ self.entry2.set_text(self._pw)
        # set old shared directory
        self.filechooserbutton1.set_current_folder(self._dir)
        
    def show(self,*args,**kwargs):
        self.update()
        self.window1.show()
        
    def hide(self,*args,**kwargs):
        self.window1.hide()

       
    def GUI_serving(self):
        self.button2.set_label("Stop Serving")
        self.entry1.set_sensitive(False)
        self.entry2.set_sensitive(False)
        self.checkbutton1.set_sensitive(False)
        self.checkbutton2.set_sensitive(False)
        self.spinbutton1.set_sensitive(False)
        self.filechooserbutton1.set_sensitive(False)
        self.window1.hide()
        #self.button1.set_sensitive(True)
        #self.button2.set_sensitive(False)

        #start/stop serving
    def on_button2_clicked(self, widget):
        self.parent.shares=[(True,[self.entry1.get_text(),self.entry2.get_text(),self._dir,"elradfmw" if self.checkbutton3.get_active() else "elr"]),]
        self.parent.toggle_server()
        
    
    # quit
    def GUI_not_serving(self):
        #self.proc.terminate()
        #self.proc = None
        self.button2.set_label("Start Serving")
        if not self.anonymous:
            self.entry1.set_sensitive(True)
            self.entry2.set_sensitive(True)
            self.checkbutton1.set_sensitive(True)
        self.checkbutton2.set_sensitive(True)
        self.spinbutton1.set_sensitive(True)
        self.filechooserbutton1.set_sensitive(True)
        #self.button1.set_sensitive(False)
        #self.button2.set_sensitive(True)
        
    def on_button1_clicked(self, widget):
        if self.parent.running:
            self.parent.toggle_server()
        
        self.parent._dump_config()
        gtk.main_quit()
        

    def on_filechooserbutton1_selection_changed(self, widget):
        self._dir = self.filechooserbutton1.get_current_folder_uri()[7:]

    def on_checkbutton1_toggled(self, widget):
        self.entry2.set_visibility(not self.entry2.get_visibility())

    def on_checkbutton3_toggled(self, widget):
        #self.write = not self.write
        pass

    def on_spinbutton1_value_changed(self, widget):
        self.port = self.spinbutton1.get_value_as_int()

    def on_checkbutton2_toggled(self, widget):
        self.anonymous = not self.anonymous
        self.__anon_sensitivity()
        
    def __anon_sensitivity(self):
        self.entry1.set_sensitive(not self.anonymous)
        self.entry2.set_sensitive(not  self.anonymous)
        self.checkbutton1.set_sensitive( not self.anonymous)
        if self.anonymous:
            self.entry1.set_text(self.parent.anon_kw)
            self.entry2.set_text('')
            self.checkbutton3.set_active(False)
        else:
            self.entry1.set_text(self.uname)
            self.entry2.set_text(self._pw)
            self.checkbutton3.set_active(self.write)
    
    def on_window_destroy(self, widget,data=None):
        #if self.proc:
         #   self.proc.terminate()
        #gtk.main_quit()
        #print "destroy"
        self.window1.hide()
        #return True
        return True
        

